/*
 * @Author: xuetao 3168581151@qq.com
 * @Date: 2025-01-23
 * @LastEditors: xuetao 3168581151@qq.com
 * @LastEditTime: 2025-03-15
 * @Description: 联系人服务
 */
import 'package:chat_client/enums/contact_enum.dart';
import 'package:chat_client/enums/apply_enum.dart';
import 'package:chat_client/models/contact_model.dart';
import 'package:chat_client/models/apply_model.dart';
import 'package:chat_client/services/api_service.dart';
import 'package:chat_client/services/socket/conversation_service.dart'
    show ConversationService;

import 'package:chat_client/repositories/contact_repository.dart';

class ContactService {
  // 单例模式
  ContactService._internal();
  static final ContactService _instance = ContactService._internal();
  static ContactService get instance => _instance;

  final ApiService apiService = ApiService.instance;
  final ContactRepository contactRepository = ContactRepository.instance;

  /// 搜索用户
  Future searchUser(String text) async {
    // 判断是否是纯数字，纯数字则为电话号码
    bool isPhoneNumber = RegExp(r'^\d+$').hasMatch(text);

    // 根据是否是电话号码来判断查询条件
    final params = <String, dynamic>{};
    if (isPhoneNumber) {
      params['phoneNumber'] = text; // 如果是电话号码
    } else {
      params['username'] = text; // 如果是用户名
    }
    // 调用API
    final response = await apiService.get('/contact/search', params: params);
    response['data']['source'] = isPhoneNumber ? '手机号' : '用户名';
    return response['data'];
  }

  /// 发送申请
  Future sendFriendRequest({
    required userId,
    required String applyInfo,
  }) async {
    if (userId != null) {
      final isExistApply = contactRepository.getApply(userId);
      // 如果该用户已经向本用户发送了待处理好友申请
      if (isExistApply != null &&
          !isExistApply.isSend &&
          isExistApply.status == ApplyStatus.pending.value) {
        throw Exception('请前往处理该用户的好友申请');
      }

      final response = await apiService.post('/contact/apply/send', {
        'receiverId': userId,
        'applyInfo': applyInfo,
      });

      final apply = Apply.fromJson(response['data']['apply'], true);
      await contactRepository.setApply(apply);

      /// 对方自动接收好友申请时
      final json = response['data']['contact'];
      if (json != null) {
        final contact = Contact.fromJson(json);
        await contactRepository.setContact(contact);
      }
      // 储存申请到本地
      return response['message'];
    }
  }

  /// 获取远程好友请求列表, 并储存到本地
  Future getRemoteFriendRequestList() async {
    final response = await apiService.get('/contact/apply/list');
    final applyList = response['data']['applyList'];
    if (applyList != null) {
      await contactRepository.setApplyList(Apply.fromJsonList(applyList));
    }
  }

  // 获取本地好友请求列表
  List<Apply> getLocalFriendRequestList() {
    return contactRepository.getAllApplyList();
  }

  /// 处理好友请求
  Future<String> handleFriendRequest(
    String senderId,
    bool isAccepted,
    String? applyInfo,
  ) async {
    final response = await apiService.post('/contact/apply/handle', {
      'senderId': senderId,
      'isAccepted': isAccepted,
    });

    // 修改本地请求的状态
    await contactRepository.updateApply(
      opponentId: senderId,
      status:
          isAccepted ? ApplyStatus.accepted.value : ApplyStatus.rejected.value,
    );

    // 储存联系人信息
    if (response['data'] != null && isAccepted) {
      final contact = Contact.fromJson(response['data']);
      await contactRepository.setContact(contact);
    }

    return response['message'];
  }

  // 获取远程联系人列表, 并储存到本地
  Future getRemoteContactList() async {
    final response = await apiService.get('/contact/list');
    final contactList = response['data']['contactList'];
    if (contactList != null) {
      await contactRepository
          .setContactgetContactList(Contact.fromJsonList(contactList));
    }
  }

  // 获取本地联系人列表
  List<Contact> getLocalContactList() {
    return contactRepository.getContactList();
  }

  // 获取本地联系人
  Contact getLocalContact(userId) {
    final Contact? contact = contactRepository.getContact(userId);
    if (contact == null) throw ApiError(message: 'Contact 不存在于数据库');
    return contact;
  }

  // 获取本地黑名单列表
  List<Contact> getLocalBlockList() {
    return contactRepository.getBlockList();
  }

  // 备注好友
  Future remark({required String contactId, required String remark}) async {
    final response = await apiService
        .put('/contact/remark', {'contactId': contactId, 'remark': remark});
    print(response);
    return response;
  }

  // 删除好友
  Future deleteFriend(String contactId) async {
    final response = await apiService
        .delete('/contact/delete', data: {'contactId': contactId});
    print(response);
    return response;
  }

  // 处理用户拉黑
  Future<String> handleBlackUser(String userId, bool unBlacked) async {
    // unBlacked true表示解除拉黑
    final url = unBlacked ? '/contact/unblock' : '/contact/block';
    final response = await apiService.post(url, {'targetUserId': userId});
    if (unBlacked) {
      // 解除拉黑
      final String targetUserId = response['data']['contact'];
      final int status = response['data']['status'];
      if (status == ContactStatus.delete.value) {
        await contactRepository.deleteContact(targetUserId);
      }
    } else {
      // 拉黑
      final blackContact = Contact.fromJson(response['data']['contact']);
      await contactRepository.setContact(blackContact);
      final applyModifiedCount = response['data']['applyModifiedCount'];
      if (applyModifiedCount > 0) {
        await contactRepository.updateApply(
            opponentId: blackContact.userId, status: ApplyStatus.overdue.value);
      }
    }
    return response['message'];
  }

  /// 获取好友信息 （自动处理好友申请）
  Future<Contact?> getFriendInfo(String userId) async {
    final response =
        await apiService.post('/contact/contact-info', {'contactId': userId});

    final json = response['data']['contact'];
    late Contact? contact;
    if (json != null) {
      contact = Contact.fromJson(json);
      await contactRepository.setContact(contact);
    }
    return contact;
  }

  /// 修改联系人会话Id
  Future updateCoversationId(String conversationId, String contactId) async {
    final Contact? contact = await getContactSafe(contactId);
    if (contact == null) throw Error();
    final newContact = contact.copyWith(conversationId: conversationId);
    await contactRepository.setContact(newContact);
  }

  // 获取联系人(保险版)
  Future<Contact?> getContactSafe(userId) async {
    final Contact? contact = contactRepository.getContact(userId);
    return contact ?? getFriendInfo(userId);
  }
}
